package game.entity.actor;


import edu.monash.fit2099.engine.*;
import game.entity.action.*;
import game.entity.behavior.*;
import game.interfaces.Vegetarian;
import game.entity.item.Fruit;
import game.util.RandomUtil;

import java.util.List;

/**
 * A herbivorous dinosaur. 剑龙
 */
public class Stegosaur extends Actor implements Vegetarian {
    // Will need to change this to a collection if Stegosaur gets additional Behaviours.
    protected Behaviour behaviour;
    protected String sex;
    protected int sleepTurn =1;
    protected int pregnancyTurn =1 ;
    // protected int birthTurn =10 ;
    protected int birthTurn =3 ;
    protected  final int DEAD_TURN = 20;
    protected final int HUNGRY_POINTS = 90;
    /**
     * Constructor.
     * All Stegosaurs are represented by a 'd' and have 100 hit points.
     *
     * @param name the name of this Stegosaur
     */
    public Stegosaur(String name, String sex,int hitpoints) {
        super(name+ RandomUtil.randomInt(), 'S', hitpoints);
        this.sex = sex;
        behaviour = new WanderBehaviour();
        maxHitPoints = 100;
    }
    public Stegosaur(String name, String sex) {
        this(name,sex,50);
    }


    @Override
    public Actions getAllowableActions(Actor otherActor, String direction, GameMap map) {
        Actions actions = new Actions();

//        繁殖
        String sex = otherActor.getSex();
        if (otherActor instanceof Stegosaur
                && !(behaviour instanceof PregnancyBehaviour)
                && isOppositeSex(sex)) {
//			返回交配action
            actions.add(new SexAction(this));
        }

//        饥饿，且player有水果，可被喂食
        if(behaviour instanceof HungerBehaviour || behaviour instanceof SleepBehaviour){
            List<Item> inventory = otherActor.getInventory();
            for (Item item : inventory) {
                if(item instanceof Fruit){
                    actions.add(new FeedAction(this,item));
                }
            }
        }
        actions.add(new AttackAction(this));
        return actions;
    }

    /**
     * 给你一系列可能的事件，每个角色根据behavior选择出下一步要触发的事件
     * Figure out what to do next.
     * <p>
     * FIXME: Stegosaur wanders around at random, or if no suitable MoveActions are available, it
     * just stands there.  That's boring.
     *
     * @see edu.monash.fit2099.engine.Actor#playTurn(Actions, Action, GameMap, Display)
     */
    @Override
    public Action playTurn(Actions actions, Action lastAction, GameMap map, Display display) {

//        昏迷状态,每回合计次； 持续20回合时，删除该角色
        if(behaviour instanceof SleepBehaviour){
            if(sleepTurn == DEAD_TURN ){
                sleepTurn = 1;
                behaviour = new DeathBehaviour(this);
            }else{
                sleepTurn+=1;
                return behaviour.getAction(this,map);
            }
        }
        if(behaviour instanceof PregnancyBehaviour){
            if(pregnancyTurn == birthTurn){
                pregnancyTurn = 1;
                return new BirthAction();
            }else{
                // System.out.println(name + "正在怀孕，当前怀孕轮次："+pregnancyTurn);
                pregnancyTurn+=1;
                return behaviour.getAction(this,map);
            }
        }
//        周围事件如果满足触发条件，则直接触发
        for (Action action : actions) {
//           周围存在食物
            if (hitPoints < 90 && action instanceof EatAction) {
                return action;
            }
//            周围存在异性
            if (hitPoints >= 90 && !(behaviour instanceof PregnancyBehaviour)
                    && action instanceof SexAction) {
                return action;
            }
        }

//        周围事件不满足，再执行自己的事件
        if(hitPoints == 0){//            无意识状态
            behaviour = new SleepBehaviour(this);
        } else if (0 < hitPoints && hitPoints < HUNGRY_POINTS) {
            behaviour = new HungerBehaviour(this);
        } else if(hitPoints > HUNGRY_POINTS) {
            behaviour = new Want2SexBehaviour(this);
        }

        hitPoints --;
        return behaviour.getAction(this,map);
    }

    @Override
    public String getSex() {
        return this.sex;
    }

    @Override
    public Behaviour setBehaviour(Behaviour behaviour) {
        this.behaviour = behaviour;
        return this.behaviour;
    }

    @Override
    public Behaviour getBehavior() {
        return this.behaviour;
    }

    @Override
    public int getHitPoints() {
        return hitPoints;
    }
}
